﻿using System;
using System.IO;
using Moebius.Core;
using Moebius.Rendering;
using NUnit.Framework;
using Rhino.Mocks;
using Rhino.Mocks.Constraints;

namespace Moebius.Tests.Core
{
    [TestFixture]
    public class ResourceFactoryTest
    {
        private ResourceFactory factory;
        private MockRepository mockRepository;
        private ResourceManager resourceManager;

        [TestFixtureSetUp]
        public void OneTimeSetup()
        {
            if (!File.Exists("unknown.unknown")) File.Create("unknown.unknown");
            if (!File.Exists("resource.resource")) File.Create("resource.resource");
        }

        #region Test Initialization: Create A ResourceFactory

        [SetUp]
        public void SetUp()
        {
            factory = new ResourceFactory();
            mockRepository = new MockRepository();
            resourceManager = mockRepository.CreateMock<ResourceManager>();
        }

        #endregion
        #region Test Teardown

        [TearDown]
        public void TearDown()
        {
            mockRepository.ReplayAll();
            mockRepository.VerifyAll();
        }

        #endregion

        #region Test: Loading Nonexistant Files throws FileNotFound

        [Test]
        [ExpectedException(typeof(FileNotFoundException))]
        public void TestLoadingBadFilesThrowsFileNotFound()
        {
            factory.Load<int>(@"c:\..\..\badFile.bmp");
        }

        #endregion
        #region Test: Files Require An Extension

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void TestFilesNeedAnExtension()
        {
            factory.Load<int>("resource");
        }

        #endregion
        #region Test: ResourceManagers Load Files

        [Test]
        public void TestResourceManagersLoadFiles()
        {
            Expect.Call(resourceManager.LoadResource(null, null))
                .Constraints(Is.Equal("resource.resource"), Is.Same(factory))
                .Return(null);

            mockRepository.ReplayAll();

            factory.RegisterResourceManager(new string[] { ".resource" }, resourceManager);
            factory.Load<string>("resource.resource");

            mockRepository.VerifyAll();
        }

        #endregion
        #region Test: Unknown Files Are Not Loaded

        [Test]
        public void TestUnknownFilesAreNotLoaded()
        {
            // Should never touch the resource factory either.
            Expect.Call(resourceManager.LoadResource(null, null)).Repeat.Never();
            mockRepository.ReplayAll();

            Assert.IsNull(factory.Load<string>("unknown.unknown"));
        }

        #endregion
        #region Test: Resource Manager Can Handle Multiple File Types

        [Test]
        public void TestResourceManagerCanHandleManyFileTypes()
        {
            Expect.Call(resourceManager.LoadResource(null, null))
                .Constraints(Is.Equal("unknown.unknown"), Is.Same(factory)).Return(null);

            Expect.Call(resourceManager.LoadResource(null, null))
                .Constraints(Is.Equal("resource.resource"), Is.Same(factory)).Return(null);

            mockRepository.ReplayAll();

            factory.RegisterResourceManager(new string[] { ".unknown", ".resource" }, resourceManager);
            factory.Load<string>("unknown.unknown");
            factory.Load<string>("resource.resource");

            mockRepository.VerifyAll();
        }

        #endregion
    }
}
